package com.fanghuyun.iswaf.filter;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.fanghuyun.iswaf.common.Constants;
import com.fanghuyun.iswaf.common.SysConfig;
import com.fanghuyun.iswaf.function.Extension;
import com.fanghuyun.iswaf.function.FileMode;
import com.fanghuyun.iswaf.function.SqlInject;
import com.fanghuyun.iswaf.function.Struts;
import com.fanghuyun.iswaf.function.Upload;
import com.fanghuyun.iswaf.function.WebServer;
import com.fanghuyun.iswaf.function.WebShell;
import com.fanghuyun.iswaf.function.Xss;
import com.fanghuyun.iswaf.util.StringUtil;

public class DoFilter extends IsWaf{
	
	private static SysConfig sysConfig = null;
	
	Logger logger = Logger.getLogger("iswaf.client");
	
	/**
	 * Get SysConfig Object
	 * @return
	 */
	public static SysConfig getSysConfig(){
		if(sysConfig==null){
			synchronized (SysConfig.class) {
				return sysConfig=new SysConfig();
			}
		}
		return sysConfig;
	}

	public boolean upload(HttpServletRequest request, Map<String, Object> wrapper,Properties properties) {
		return Upload.checkUpload(request,wrapper,properties);
	}

	public Map<String, Object> sqlInject(HttpServletRequest request, Map<String, Object> wrapper,Properties properties) {
		return SqlInject.checkInject(request,wrapper,properties);
	}

	public Map<String, Object> xss(HttpServletRequest request, Map<String, Object> wrapper,Properties properties) {
		return Xss.CheckXss(request,wrapper,properties);
	}

	public boolean server(HttpServletRequest request, HttpServletResponse response,Properties properties) {
		return WebServer.safe(request,properties);
	}

	public boolean webshell(HttpServletRequest request,HttpServletResponse response,Properties properties) {
		return WebShell.webShell(request,properties);
	}
	
	public boolean struts(HttpServletRequest request, Map<String, Object> wrapper,Properties properties) {
		return Struts.pocCheck(request,wrapper,properties);
	}

	public boolean fileMode(HttpServletRequest request, Map<String, Object> wrapper,Properties properties) {
		return FileMode.checkFileMode(request,wrapper,properties);
	}
	
	public boolean extension(HttpServletRequest request,Map<String, Object> wrapper,Properties properties) {
		return Extension.extCheck(request,properties);
	}
	
	/**
	 * function init,init all of the attrack function
	 * @param request
	 * @param response
	 * @return result contants HttpRequest wapper and next action
	 * @throws Exception
	 */
	public Map<String,Object> functionInit(HttpServletRequest request,HttpServletResponse response) throws Exception{
		Map<String,Object> result = null;
		try {
			result = new HashMap<String, Object>();
			result.put("doChain", false);//default doChain false
			SysConfig config = getSysConfig();
			Properties properties = config.getSysConfigProperties();
			Map<String, Object> wrapper = config.getRequestParameter(request);
			String function = properties.getProperty("function.open");
			if(StringUtil.isNotEmpty(function)){
				for(String s :function.toLowerCase().trim().split(",")){
					boolean deny = Constants.SYS_CONFIG_REQUEST_DENY.equals(properties.getProperty("function."+s+".action"));
					if(s.equals(Constants.SYS_FUNCTION_UPLOAD)){
						if(deny&&upload(request, wrapper,properties)){
							return result;
						}
					}
					if(s.equals(Constants.SYS_FUNCTION_WEBSHELL)){
						webshell(request, response,properties);
					}
					if(s.equals(Constants.SYS_FUNCTION_SQLINJECT)){
						wrapper = sqlInject(request, wrapper,properties);
						result.put("doChain", true);
					}
					if(s.equals(Constants.SYS_FUNCTION_WEB_SERVERS)){
						if(deny&&server(request, response,properties)){
							return result;
						}
					}
					if(s.equals(Constants.SYS_FUNCTION_XSS)){
						wrapper = xss(request, wrapper,properties);
						result.put("doChain", true);
					}
					if(s.equals(Constants.SYS_FUNCTION_STRUTS_RULES)){
						if(deny&&struts(request, wrapper,properties)){
							return result;
						}
					}
					if(s.equals(Constants.SYS_FUNCTION_EXT_RULES)){
						if(deny&&extension(request, wrapper,properties)){
							return result;
						}
					}
				}
				result.put(Constants.APP_FILTER_HTTPREQUEST_WRAPPER, wrapper);
			}else{
				logger.error("Loadding config error.");
			}
		} catch (Exception e) {
			logger.error("System error.",e);
			throw e;
		}
		return result;
	}

}
